//
//  SimplePlayerController.swift
//  简单的音乐播放实现
//  主要测试音乐播放相关逻辑
//  因为黑胶唱片界面的逻辑比较复杂
//  如果在和播放相关逻辑混一起，不好实现
//  所有我们可以先使用一个简单的播放器
//  从而把播放器相关逻辑实现完成
//  然后在对接的黑胶唱片
//  就相对来说简单一点
//
//  Created by smile on 2019/6/23.
//  Copyright © 2019 ixuea. All rights reserved.
//

import UIKit

class SimplePlayerController: BaseTitleController {
    
    
    /// 音乐播放列表
    @IBOutlet weak var tableView: UITableView!
    
    
    /// 标题
    @IBOutlet weak var lbTitle: UILabel!
    
    
    /// 当前播放时间
    @IBOutlet weak var lbStart: UILabel!
    
    
    /// 进度条
    @IBOutlet weak var sdProgress: UISlider!
    
    
    /// 音乐总时间
    @IBOutlet weak var lbEnd: UILabel!
    
    
    /// 播放按钮
    @IBOutlet weak var btPlay: UIButton!
    
    
    /// 循环模式
    @IBOutlet weak var btLoopModel: UIButton!
    
    /// 播放管理器
    var musicPlayerManager:MusicPlayerManager!
    
    /// 播放列表管理器
    var playListManager:PlayListManager!
    
    
    /// 是否按下了进度条
    var isSlideTouch = false
    
    
    override func initDatas() {
        super.initDatas()
        
        //测试单例设计模式
        //查看两个对象的内存地址是否一样
        //如果一样就表示单例设置模式生效了
//        let o1 = MusicPlayerManager.shared()
//        let o2 = MusicPlayerManager.shared()
        
        print("SimplePlayerController initDatas")
        
        //获取音乐播放管理器
        musicPlayerManager = MusicPlayerManager.shared()
        
        //获取播放列表管理器
        playListManager = PlayListManager.shared
        
        //测试音乐数据
//        let songUrl = "http://dev-courses-misuc.ixuea.com/assets/s1.mp3"
//
//        let song = Song()
//        song.uri = songUrl
//
//        //播放
//        musicPlayerManager.play(songUrl, song)
        
        initPlayData()
        
        //显示循环模式
        showLoopModel()
    }
    
    /// 显示播放数据
    func initPlayData() {
        //显示初始化数据
        showInitData()
        
        //显示播放状态
        showMusicPlayStatus()
        
        //显示音乐时长
        showDuration()
        
        //显示进度
        showProgress()
    }
    
    override func initListeners() {
        super.initListeners()
        
        //监听应用进入前台了
        NotificationCenter.default.addObserver(self, selector: #selector(onEnterForeground), name: UIApplication.didBecomeActiveNotification, object: nil)
        
        //监听应用进入后台了
        NotificationCenter.default.addObserver(self, selector: #selector(onEnterBackground), name: UIApplication.willResignActiveNotification, object: nil)
    }
    
    /// 进入前台了
    @objc func onEnterForeground() {
        print("SimplePlayerController onEnterForeground")
        
        //显示播放数据
        initPlayData()
        
        //选中当前播放的音乐
        scrollPosition()
        
        //设置播放代理
        musicPlayerManager.delegate = self
    }
    
    /// 进入前台了
    @objc func onEnterBackground() {
        print("SimplePlayerController onEnterBackground")
        
        //取消播放代理
        musicPlayerManager.delegate = nil
    }
    
    // MARK: - 按钮相关事件
    
    /// 播放或者暂停
    func playOrPause() {
        if musicPlayerManager.isPlaying() {
            playListManager.pause()
        } else {
            playListManager.resume()
        }
    }
    
    /// 上一曲s
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onPreviousClick(_ sender: Any) {
        print("SimplePlayerController onPreviousClick")
        
        let song = playListManager.previous()
        playListManager.play(song)
    }
    
    
    /// 播放按钮
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onPlayClick(_ sender: Any) {
        print("SimplePlayerController onPlayClick")
        
        playOrPause()
    }
    
    
    /// 下一曲
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onNextClick(_ sender: Any) {
        print("SimplePlayerController onNextClick")
        
        playListManager.play(playListManager.next())
    }
    
    /// 循环模式
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onLoopModelClick(_ sender: Any) {
        print("SimplePlayerController onLoopModelClick")
        
        //切换循环模式
        playListManager.changeLoopModel()
        
        //显示当前循环模式
        showLoopModel()
    }
    
    /// 显示循环模式
    func showLoopModel() {
        //获取当前循环模式
        let model = playListManager.getLoopModel()
        
        switch model {
        case .list:
            btLoopModel.setTitle("列表循环", for: .normal)
        case .random:
            btLoopModel.setTitle("随机循环", for: .normal)
        default:
            btLoopModel.setTitle("单曲循环", for: .normal)
        }
    }
    
    // MARK: - 进度条相关
    
    /// 进度条拖拽回调
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onProgressChanged(_ sender: UISlider) {
        //将拖拽进度显示到界面
        //用户就很方便的知道自己拖拽到什么位置
        lbStart.text = TimeUtil.second2MinuteAndSecond(sender.value)
        
        //音乐切换到拖拽位置播放
//        musicPlayerManager.seekTo(sender.value)
    }
    
    
    /// 进度条按下
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onSlideTouchDown(_ sender: UISlider) {
        print("SimplePlayerController onSlideTouchDown")
        
        isSlideTouch=true
    }
    
    
    /// 进度条抬起
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onSlideTouchUp(_ sender: UISlider) {
        print("SimplePlayerController onSlideTouchUp")
        
        isSlideTouch = false
        
        if sender.value > 1 {
            //减一是为了用户能听清前一秒
            //音乐可能没那么明显
            //但视频继续播放的时候最好减一秒
            playListManager.seekTo(sender.value-1)
        }
    }
    
    // MARK: - 播放相关
    
    /// 滚动（选中）到当前音乐的位置
    func scrollPosition() {
        //获取当前音乐在播放列表中的索引
        let data = playListManager.data!
        
        let playListOC = playListManager.getPlayList() as NSArray
        
        let index = playListOC.index(of: data)
        
        if index != -1 {
            //创建indexPath
            let indexPath = IndexPath(item: index, section: 0)
            
            //延迟后选中当前音乐
            //因为前面执行可能是删除Cell操作
            DispatchQueue.main.asyncAfter(deadline: .now()+1.0) {
                //选中
                self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: .middle)
            }
        }
        
    }
    
    /// 显示初始化音乐数据
    func showInitData() {
        let data = playListManager.data!
        
        //显示标题
        lbTitle.text = data.title
    }
    
    /// 显示播放状态
    func showPlayStatus()  {
        btPlay.setTitle("播放", for: .normal)
    }
    
    /// 显示暂停状态
    func showPauseStatus() {
        btPlay.setTitle("暂停", for: .normal)
    }
    
    /// 显示播放状态
    func showMusicPlayStatus() {
        if musicPlayerManager.isPlaying() {
            showPauseStatus()
        } else {
            showPlayStatus()
        }
    }
    
    /// 显示播放总时长
    func showDuration() {
        let duration = musicPlayerManager.data!.duration
        
        if duration > 0 {
            lbEnd.text = TimeUtil.second2MinuteAndSecond(duration)
            sdProgress.maximumValue = duration
        }
    }
    
    /// 显示进度
    func showProgress() {
        let progress = musicPlayerManager.data!.progress
        
        if progress > 0 {
            if !isSlideTouch {
                lbStart.text = TimeUtil.second2MinuteAndSecond(progress)
                sdProgress.value = progress
            }
        }
    }
    
    /// 视图即将可见方法
    ///
    /// - Parameter animated: <#animated description#>
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        //设置播放代理
        musicPlayerManager.delegate = self
    }
    
    /// 视图已经可见了
    ///
    /// - Parameter animated: <#animated description#>
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        scrollPosition()
    }
    
    /// 视图即将消失
    ///will：即将
    ///did：已经
    ///其他方法命名也都有这个规律
    ///
    /// - Parameter animated: <#animated description#>
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        //取消代理
        musicPlayerManager.delegate = nil
    }
    
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}

// MARK: - 启动界面
extension SimplePlayerController {
    
    /// 启动界面
    ///
    /// - Parameter navigationController: <#navigationController description#>
    static func start(_ navigationController:UINavigationController) {
        //创建控制器
        let controller = navigationController.storyboard!.instantiateViewController(withIdentifier: "SimpletPlayer")
        
        //将控制器压入导航控制器
        navigationController.pushViewController(controller, animated: true)
    }
}

// MARK: - 播放代理
extension SimplePlayerController: MusicPlayerDelegate {
    
    /// 播放器准备完毕了
    ///
    /// - Parameter data: <#data description#>
    func onPrepared(_ data: Song) {
        print("SimplePlayController onPrepared duration:\(data.duration)")
        showInitData()
        
        showDuration()
        
        scrollPosition()
    }
    
    /// 暂停了
    ///
    /// - Parameter data: <#data description#>
    func onPaused(_ data: Song) {
        showPlayStatus()
    }
    
    /// 播放中
    ///
    /// - Parameter data: <#data description#>
    func onPlaying(_ data: Song) {
        showPauseStatus()
    }
    
    /// 进度回调
    ///
    /// - Parameter data: <#data description#>
    func onProgress(_ data: Song) {
        print("SimplePlayerController onProgress:\(data.progress),\(data.duration)")
        
        showProgress()
    }
    
    /// 歌词信息改变了
    ///
    /// - Parameter data: <#data description#>
    func onLyricChanged(_ data: Song) {
        print("SimplePlayerController onLyricChanged:\(data.style),\(data.lyric)")
    }
}

// MARK: - 列表数据源和代理
extension SimplePlayerController: UITableViewDataSource,UITableViewDelegate {
    
    /// 返回有多少个数据
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return playListManager.getPlayList().count
    }
    
    /// 返回当前位置的Cell
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - indexPath: <#indexPath description#>
    /// - Returns: <#return value description#>
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        //获取当前位置的数据
        let data = playListManager.getPlayList()[indexPath.row]
        
        let cell = tableView.dequeueReusableCell(withIdentifier: CELL)!
        
        //设置值
        cell.textLabel!.text = data.title
        
        //返回Cell
        return cell
        
    }
    
    /// 点击了Cell回调
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - indexPath: <#indexPath description#>
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        //获取当前点击的这首音乐
        let data = playListManager.getPlayList()[indexPath.row]
        
        //播放
        playListManager.play(data)
    }
    
    /// 返回当前Cell是否可以编辑
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - indexPath: <#indexPath description#>
    /// - Returns: <#return value description#>
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }
    
    /// 编辑按钮样式
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - indexPath: <#indexPath description#>
    /// - Returns: <#return value description#>
    func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
        return .delete
    }
    
    /// 返回编辑按钮的标题
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - indexPath: <#indexPath description#>
    /// - Returns: <#return value description#>
    func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
        return "删除"
    }
    
    /// 触发了删除动作后回调
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - editingStyle: <#editingStyle description#>
    ///   - indexPath: <#indexPath description#>
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        print("SimplePlayerController commit edit:\(indexPath.row)")
        
        //获取到当前这首音乐
        let data = playListManager.getPlayList()[indexPath.row]
        
        //从播放列表中删除
        playListManager.delete(data)
        
        //删除Cell
        tableView.deleteRows(at: [indexPath], with: UITableView.RowAnimation.automatic)
        
        //判断是否要关闭播放界面
        if playListManager.data == nil {
            //表示没有音乐了
            navigationController!.popViewController(animated: true)
        }
    }
}
